package com.cskaoyan.wordmemorize.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cskaoyan.wordmemorize.converter.VocConverter;
import com.cskaoyan.wordmemorize.dao.entity.*;
import com.cskaoyan.wordmemorize.dao.mapper.*;
import com.cskaoyan.wordmemorize.dto.admin.VocExcelDTO;
import com.cskaoyan.wordmemorize.request.ExampleSentenceCommand;
import com.cskaoyan.wordmemorize.request.VocChapBookCommand;
import com.cskaoyan.wordmemorize.request.VocCommand;
import com.cskaoyan.wordmemorize.request.VocMeaningCommand;
import com.cskaoyan.wordmemorize.service.VocService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

@Slf4j
public class VocExcelImportListener implements ReadListener<VocExcelDTO> {


    private static final int BATCH_COUNT = 100;
    private List<VocCommand> cachedDataList = new ArrayList<>(BATCH_COUNT);

    VocConverter vocConverter;
    VocMapper vocMapper;
    VocChapBookMapper vocChapBookMapper;
    VocMeaningMapper vocMeaningMapper;
    ExampleSentenceMapper exampleSentenceMapper;
    VocBookMapper vocBookMapper;
    VocChapterMapper vocChapterMapper;


    private int totalCount = 0;

    public VocExcelImportListener(VocConverter vocConverter, VocMapper vocMapper, VocChapBookMapper vocChapBookMapper, VocMeaningMapper vocMeaningMapper, ExampleSentenceMapper exampleSentenceMapper, VocBookMapper vocBookMapper, VocChapterMapper vocChapterMapper) {
        this.vocConverter = vocConverter;
        this.vocMapper = vocMapper;
        this.vocChapBookMapper = vocChapBookMapper;
        this.vocMeaningMapper = vocMeaningMapper;
        this.exampleSentenceMapper = exampleSentenceMapper;
        this.vocBookMapper = vocBookMapper;
        this.vocChapterMapper = vocChapterMapper;
    }

    @Override
    public void invoke(VocExcelDTO data, AnalysisContext context) {
        totalCount++;
        try {
            // 转换为VocCommand
            VocCommand command = convertToCommand(data);
            cachedDataList.add(command);

            // 达到批量处理阈值
            if (cachedDataList.size() >= BATCH_COUNT) {
                saveBatch();
                cachedDataList = new ArrayList<>(BATCH_COUNT);
            }
        } catch (Exception e) {
            int rowIndex = context.readRowHolder().getRowIndex() + 1;
            //log.error("第{}行处理失败: {}", rowIndex, e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 处理最后一批数据
        if (!cachedDataList.isEmpty()) {
            saveBatch();
        }
        log.info("Excel导入完成，共处理{}行数据", totalCount);
    }

    @Override
    public boolean hasNext(AnalysisContext context) {
        return ReadListener.super.hasNext(context);
    }
    private void saveBatch() {
        log.info("开始批量保存{}个单词", cachedDataList.size());
        for (VocCommand command : cachedDataList) {
            try {
                addVoc(command);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("单词[{}]保存失败: {}", command.getContent(), e.getMessage());
            }
        }
    }

    private VocCommand convertToCommand(VocExcelDTO data) {
        VocCommand command = new VocCommand();
        command.setContent(data.getContent());
        command.setUkPhonetic(data.getUkPhonetic());
        command.setUsPhonetic(data.getUsPhonetic());
        command.setUkPronounciation(data.getUkPronounciation());
        command.setUsPronounciation(data.getUsPronounciation());

        // 解析书籍章节关系
        if (StringUtils.isNotBlank(data.getBookInfos())) {
            String[] parts = data.getBookInfos().split("#", 2);
            if (parts.length == 2) {
                VocChapBookCommand relation = new VocChapBookCommand();
                relation.setBookName(parts[0]);
                relation.setChapterName(parts[1]);
                command.setRelations(Collections.singletonList(relation));
            }
        }

        // 解析单词释义
        if (StringUtils.isNotBlank(data.getInterpretations())) {
            List<VocMeaningCommand> meanings = new ArrayList<>();
            String[] interpretationLines = data.getInterpretations().split("\n");
            for (String line : interpretationLines) {
                if (line.matches("^.+\\..+$")) {
                    int dotIndex = line.indexOf('.');
                    VocMeaningCommand meaning = new VocMeaningCommand();
                    meaning.setType(line.substring(0, dotIndex).trim());
                    meaning.setInterContent(line.substring(dotIndex + 1).trim());
                    meanings.add(meaning);
                }
            }
            command.setInterpretations(meanings);
        }

        // 解析例句
        if (StringUtils.isNotBlank(data.getExampleSentences())) {
            List<ExampleSentenceCommand> examples = new ArrayList<>();
            String[] exampleLines = data.getExampleSentences().split("\n");
            // 每两行一组（英文和中文）
            for (int i = 0; i < exampleLines.length; i += 2) {
                if (i + 1 < exampleLines.length) {
                    ExampleSentenceCommand example = new ExampleSentenceCommand();
                    example.setContent(exampleLines[i].trim());
                    example.setMeaning(exampleLines[i + 1].trim());
                    examples.add(example);
                }
            }
            command.setExamples(examples);
        }

        return command;
    }

    public int getTotalCount() {
        return totalCount;
    }
    public void addVoc(VocCommand command) {
        // 将单词的基本信息保存到voc表中
        VocDO vocDO = vocConverter.command2VocDO(command);
        vocMapper.insert(vocDO);

        // 保存关系
        List<VocChapBookDO> relations = vocConverter.commands2VocChapBookDOs(command.getRelations());
        if (relations != null) {
            for (VocChapBookDO vocChapBookDO : relations) {
                // 设置单词id
                vocChapBookDO.setVocId(vocDO.getId());
                vocChapBookMapper.insert(vocChapBookDO);

                // 修改书籍和章节关联的单词数量
                if (vocChapBookDO.getChapterId() != null) {
                    // 关联到了一个章节
                    LambdaUpdateWrapper<VocChapterDO> vocChapterWrapper = new LambdaUpdateWrapper<>();
                    vocChapterWrapper.eq(VocChapterDO::getId, vocChapBookDO.getChapterId())
                            // set voc_count = voc_count + 1
                            .setSql("voc_count = voc_count + 1");

                    vocChapterMapper.update(null, vocChapterWrapper);
                }

                // 更新书籍关联的单词数量
                // 关联到了一个章节
                LambdaUpdateWrapper<VocBookDO> vocBookWrapper = new LambdaUpdateWrapper<>();
                vocBookWrapper.eq(VocBookDO::getId, vocChapBookDO.getBookId())
                        // set voc_count = voc_count + 1
                        .setSql("voc_count = voc_count + 1");
                vocBookMapper.update(null, vocBookWrapper);

            }
        }
        // 保存释义
        List<VocMeaningCommand> interpretations = command.getInterpretations();
        if (interpretations != null) {
            List<VocMeaningDO> vocMeaningDOs = vocConverter.commands2VocMeaningDOs(interpretations);
            for (VocMeaningDO vocMeaningDO : vocMeaningDOs) {
                vocMeaningDO.setVocId(vocDO.getId());
                vocMeaningMapper.insert(vocMeaningDO);

            }
        }
        // 保存例句
        List<ExampleSentenceCommand> examples = command.getExamples();
        if (examples != null) {
            List<ExampleSentenceDO> exampleSentenceDOS = vocConverter.commands2ExampleSentenceDOs(examples);
            for (ExampleSentenceDO exampleSentenceDO : exampleSentenceDOS) {
                exampleSentenceDO.setVocId(vocDO.getId());
                exampleSentenceMapper.insert(exampleSentenceDO);
            }
        }
    }
}
